﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text;
using Sinacor.Infra.Service.Security.Authorization;
using Sinacor.Infra.Service.Data;

namespace Sinacor.Servico.Bovespa.Acesso.ResourceAccess
{
    /// <summary>
    /// Data:   18/09/2008
    /// Autor:  Valdenir Vanalli Filho
    /// Obs:    Classe movida do arquivo VerificarAcessoFuncao.cs para um arquivo homônimo à classe.
    /// </summary>
    public partial class Acesso : BaseResourceAccess
    {
        
        /// <summary>
        /// Construtor padrão
		/// Adicionado por: rscatulin
        /// </summary>
        public Acesso()
            : base(AuthorizationContext.Current.CompanyId)
        {
        }
        
        /// <summary>
        /// Data    : 19/09/2008
        /// Autor   : Valdenir Vanalli Filho
        /// Obs.    : Transposto do módulo Comum, que será extinto.
        ///           Este método foi trazido do módulo supra referido, porém não foi encontrada,
        ///           no momento da transposição, nenhuma referência a ele.
        ///           Provavelmente é apenas um histórico do método imediatamente abaixo.
        /// </summary>
        /// <param name="colunaNome"></param>
        /// <param name="assessorInicial"></param>
        /// <param name="assessorFinal"></param>
        /// <returns></returns>
        public string ConsultarListaAssessoresOriginal(string colunaNome, int assessorInicial, int assessorFinal)
        {
            OracleDataBase dbNegocio = this.DataBase;

            string retorno = string.Empty;
            string sql = @"
                            select 
                                    distinct a.cd_assessor
                            from
                                    tcaassgru a,
                                    tcausugru b
				            where
                                    b.cd_grupo = a.cd_grupo
				                    and b.cd_usuario   = :userid 
				                    and a.cd_assessor >= :assessorinicial 
				                    and a.cd_assessor <= :assessorfinal";

            DbCommand dbCommand = dbNegocio.GetSqlStringCommand(sql);
            dbNegocio.AddInParameter(dbCommand, ":userid", DbType.Int32, AuthorizationContext.Current.UserId);
            //dbNegocio.AddInParameter(dbCommand, ":userid", DbType.Int32, 1);
            dbNegocio.AddInParameter(dbCommand, ":assessorinicial", DbType.Int32, assessorInicial);
            dbNegocio.AddInParameter(dbCommand, ":assessorfinal", DbType.Int32, assessorFinal);

            IDataReader dataReader = dbNegocio.ExecuteReader(dbCommand);

            while (dataReader.Read())
            {
                if (retorno == string.Empty)
                    retorno = "(" + colunaNome + " in (";

                retorno += dataReader[0].ToString() + ",";
            }

            dataReader.Close();

            if (retorno != string.Empty)
            {
                retorno = retorno.Substring(0, retorno.Length - 1);
                retorno += "))";
            }

            //dataReader.Close(); //excluido por duplicidade - esertorio - 200804291059 - ref issue ID0003837

            return retorno;
        }

        /// <summary>
        /// ConsultarListaAssessores
        /// Obter lista de assessores do cliente
        /// 
        /// Historico: 
        /// Data : 06/12/2007 (aprox)
        /// Autor: ???
        /// Obs. : Criacao do metodo
        /// 
        /// Data : 30/04/2008
        /// Autor: Eduardo Sertorio
        /// Obs. : Criacao de metodo (ConsultarListaAssessoresV2Teste) para tratar os resultados com nenhum, um e mais de 250 registros - esertorio - 200804301318 - ref issue ID0002944
        /// 
        /// Data    : 18/09/2008
        /// Autor   : Valdenir Vanalli Filho
        /// Obs.    : Classe trazida do módulo Comum, que será extinto.
        /// </summary>
        /// <param name="colunaNome"></param>
        /// <param name="assessorInicial"></param>
        /// <param name="assessorFinal"></param>
        /// <returns></returns>
        public string ConsultarListaAssessores(string colunaNome, int assessorInicial, int assessorFinal)
        {
            const int MAXIMO_ITENS_CLAUSULA_IN = 250; //valor 250 informado pelo analista Nemir no caso #2944 - esertorio - 200804301549 - ref issue ID0002944

            string sql = @"
                                    select 
                                            distinct a.cd_assessor
                                    from
                                            tcaassgru a,
                                            tcausugru b
        				            where
                                            b.cd_grupo = a.cd_grupo
        				                    and b.cd_usuario   = :userid 
        				                    and a.cd_assessor >= :assessorinicial 
        				                    and a.cd_assessor <= :assessorfinal";

            OracleDataBase dbNegocio = this.DataBase;
            DbCommand dbCommand = dbNegocio.GetSqlStringCommand(sql.ToString());

            dbNegocio.AddInParameter(dbCommand, ":userid", DbType.Int32, AuthorizationContext.Current.UserId);
            //dbNegocio.AddInParameter(dbCommand, ":userid", DbType.Int32, 1);
            dbNegocio.AddInParameter(dbCommand, ":assessorinicial", DbType.Int32, assessorInicial);
            dbNegocio.AddInParameter(dbCommand, ":assessorfinal", DbType.Int32, assessorFinal);

            IDataReader dataReader = dbNegocio.ExecuteReader(dbCommand);

            StringBuilder retorno = new StringBuilder();
            StringBuilder trechoClausulaSQL = new StringBuilder();
            int contador = 0;
            int resto = 1;
            bool separador = false;

            while (dataReader.Read())
            {
                contador += 1;

                if (separador)
                {
                    trechoClausulaSQL.Append(",");
                }

                //simulador resultado - ini - nao copiar para metodo de produção
                trechoClausulaSQL.Append(dataReader[0].ToString());
                //simulador resultado - fim - nao copiar para metodo de produção

                separador = true;

                System.Math.DivRem(contador, MAXIMO_ITENS_CLAUSULA_IN, out resto);

                if (resto == 0)
                {
                    //se ja tem trecho acumulado
                    if (!String.IsNullOrEmpty(retorno.ToString()))
                        //inclui operador de adicao de clausula
                        retorno.Append(" or");

                    //monta inicio da clausula IN com dois abre-parenteses
                    retorno.Append(" (");
                    retorno.Append(colunaNome);
                    retorno.Append(" in (");

                    //concatena novo trecho no sql
                    retorno.Append(trechoClausulaSQL);

                    //concatena no final da clausula IN com dois fecha-parenteses no final do trecho
                    retorno.Append("))");

                    //limpa a variavel de trecho para montar o proximo
                    trechoClausulaSQL = new StringBuilder();
                    separador = false;
                }
            }
            dataReader.Close();

            //se nao ha assessores
            if (contador == 0)
            {
                //retorna string vazio
                //TODO:EDU - teste com condição sempre falsa para evitar impacto de alteracao - 200804301319
                return " (1=0)";
            }
            //se ha apenas um assessor
            else if (contador == 1)
            {
                //monta clausula de igualdade
                retorno.Append(" (");
                retorno.Append(colunaNome);
                retorno.Append(" = ");
                retorno.Append(trechoClausulaSQL);
                retorno.Append(")");
            }
            //se ha mais que um e menos que o maximo permitido na clausula IN
            else if (contador < MAXIMO_ITENS_CLAUSULA_IN)
            {
                //monta clausula IN unica
                retorno.Append(" (");
                retorno.Append(colunaNome);
                retorno.Append(" IN (");
                retorno.Append(trechoClausulaSQL);
                retorno.Append("))");
            }
            //se ha mais que o maximo permitido e nao completou o ultimo lote
            else if (contador > MAXIMO_ITENS_CLAUSULA_IN && resto != 0)
            {
                //monta a ultima clausula IN no final das que ja foram montadas no loop principal
                retorno.Append(" OR (");
                retorno.Append(colunaNome);
                retorno.Append(" IN (");
                retorno.Append(trechoClausulaSQL);
                retorno.Append("))");
            }

            // a falta destes parenteses fechando a clausula completa 
            // causa um resultado de tamanho desconhecido
            // e provoca erro do tipo (unable to extend temp segment)
            retorno.Insert(0, "("); //incluido - esertorio - 200804302110
            retorno.Append(")"); //incluido - esertorio - 200804302110

            //retorna clausula(s) montada(s)
            return retorno.ToString();
        }

        /// <summary>
        /// Historico:
        /// Data: 06/12/2007
        /// Autor: Eduardo Sertorio
        /// Observacoes: Simula verificacao de permissao para acoes no sistema
        /// 
        /// Data: 21/01/2008
        /// Autor: Eduardo Sertorio / Flavio Pompilio
        /// Observacoes: Verifica de verdade a permissao para acoes no sistema
        /// </summary>
        public bool VerificarAcessoFuncao(BusinessEntity.Parameter.VerificarAcessoFuncao pVerificarAcessoFuncao)
        {

            //incluido - eduardo / flavio - 20080121
            //response = AccessControl.IsUserInRole(funcao);
            //Alterado em função da implementação da Infra 2.0
            return AuthorizationContext.Current.CheckUserAccess(pVerificarAcessoFuncao.Funcao);

        }

        /// <summary>
        /// TODO - PENDENTE - recuperar retorno de function
        /// 
        /// Metodo responsavel por verificar se um dado sistema esta instalado
        /// Data : 07/12/2007
        /// Autor: Diogo Milanez
        /// Obs:Criacao do metodo
        /// 
        /// Data    : 18/09/2008
        /// Autor   : Valdenir Vanalli Filho
        /// Obs.    : Método transposto do módulo Comum, que será extinto
        /// </summary>
        /// <param name="sistema"></param>
        /// <returns></returns>
        public bool VerificarSistemaInstalado(string sistema)
        {
            OracleDataBase dbAcesso = this.DataBase;
            DbCommand dbCommand;
            DbParameter parameter;
            StringBuilder sql = new StringBuilder();

            sql.Append("BEGIN ");
            sql.Append(":RET:= CASE WHEN PGE_GERAL.FGE_EXISTE_SISTEMA(:V_SSISTEMA) then 1 else 0 END; ");
            sql.Append("END; ");
            dbCommand = dbAcesso.GetSqlStringCommand(sql.ToString());
            dbAcesso.AddInParameter(dbCommand, "V_SSISTEMA", DbType.AnsiString, sistema);

            parameter = dbCommand.CreateParameter();
            parameter.ParameterName = "V_SSISTEMA";
            parameter.Direction = ParameterDirection.Input;
            parameter.DbType = DbType.AnsiString;
            parameter.Value = sistema;
            dbCommand.Parameters.Add(parameter);

            parameter = dbCommand.CreateParameter();
            parameter.ParameterName = "RET";
            parameter.Direction = ParameterDirection.ReturnValue;
            parameter.DbType = DbType.Int32;
            parameter.Value = null;
            dbCommand.Parameters.Add(parameter);

            dbAcesso.ExecuteNonQuery(dbCommand);

            return Convert.ToInt32(parameter.Value) == 1;
        }

        /// <summary>
        /// Historico:
        /// Data: 06/12/2007
        /// Autor: Eduardo Sertorio
        /// Observacoes: Simula verificacao de permissao para acoes no sistema
        /// 
        /// Data: 21/01/2008
        /// Autor: Eduardo Sertorio / Flavio Pompilio
        /// Observacoes: Verifica de verdade a permissao para acoes no sistema
        /// 
        /// Data    : 18/09/2008
        /// Autor   : Valdenir Vanalli Filho
        /// Obs.    : Transposto do módulo Comum, que será extinto
        /// </summary>
        public static bool VerificarAcessoFuncao(string funcao)
        {
            return AuthorizationContext.Current.CheckUserAccess(funcao);
        }

        /// <summary>
        /// Data : 08/05/2008
        /// Autor: Eduardo Sertorio
        /// Obs. : Criacao do metodo (ConsultarVersaoModulo) que poderia ajudar no caso - esertorio - 200805081335 - ref issue ID0004563
        /// 
        /// Data    : 19/09/2008
        /// Autor   : Valdenir Vanalli Filho
        /// Obs.    : Transposto do módulo Comum, que será extinto.
        ///           Este método foi trazido do módulo supra referido, porém não foi encontrada,
        ///           no momento da transposição, nenhuma referência a ele.
        /// </summary>
        /// <param name="modulo"></param>
        /// <returns></returns>
        public string ConsultarVersaoModulo(string modulo)
        {
            string retorno = string.Empty;
            string sql = @"SELECT TGESINST.VS_SIST_INST
                            FROM TGESINST , TGEEMPR
                            WHERE TGESINST.CD_EMPRESA = TGEEMPR.CD_EMPRESA
                            AND TGESINST.CD_SISTEMA = :MODULO
                            AND TGEEMPR.CD_USUA_ORAC = USER";

            OracleDataBase dbNegocio = this.DataBase;
            DbCommand dbCommand = dbNegocio.GetSqlStringCommand(sql.ToString());

            if (String.IsNullOrEmpty(modulo))
                modulo = "BOL";

            dbNegocio.AddInParameter(dbCommand, "::MODULO", DbType.String, modulo);

            IDataReader dataReader = dbNegocio.ExecuteReader(dbCommand);

            if (dataReader.Read())
            {
                retorno = dataReader[0].ToString();
            }

            dataReader.Close();

            return retorno;
        }
    }
}
